package com.hl.card.credit.utill;



import org.bouncycastle.util.encoders.UrlBase64;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

public class SecrityTool {

    private static final String ALGORITHM = "AES";
    private static final String path="/etc/keys/aes.key";

    String secret="Ued234fKsd3*45fLNs3-45dfk57s";
    //AES加密KEY
    static String aesKey="BWTAws7fQgOJlgLFK-xIhA..";

    /**
     * 生成密钥
     * @return
     * @throws Exception
     */
    private static SecretKey geneKey(){
        //获取一个密钥生成器实例
        KeyGenerator keyGenerator = null;
        try {
            keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        SecureRandom random = new SecureRandom();
        random.setSeed("123456".getBytes());//设置加密用的种子，密钥
        keyGenerator.init(random);
        SecretKey secretKey = keyGenerator.generateKey();
        //把上面的密钥存起来
        Path keyPath = Paths.get(path);
        try {
            Files.write(keyPath, secretKey.getEncoded());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return secretKey;
    }

    /**
     * 读取存储的密钥
     * @param keyPath
     * @return
     * @throws Exception
     */
    private static SecretKey readKey(Path keyPath) throws Exception {
        //读取存起来的密钥
        byte[] keyBytes = Files.readAllBytes(keyPath);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);
        return keySpec;
    }

    /**
     * 加密测试
     */
    public  static String getEncrypt( String content) {
        //1、指定算法、获取Cipher对象
        Cipher cipher = null;//算法是AES
        try {
            cipher = Cipher.getInstance(ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
        //2、生成/读取用于加解密的密钥
        SecretKey secretKey = SecrityTool.geneKey();
        byte[] aesByte = UrlBase64.decode(aesKey);
        SecretKeySpec skeySpec = new SecretKeySpec(aesByte, "AES");
        //3、用指定的密钥初始化Cipher对象，指定是加密模式，还是解密模式
        try {
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            //4、更新需要加密的内容
            cipher.update(content.getBytes());

        }catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }

        //5、进行最终的加解密操作
        byte[] result = new byte[0];//加密后的字节数组
        try {
            result = cipher.doFinal();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        //也可以把4、5步组合到一起，但是如果保留了4步，同时又是如下这样使用的话，加密的内容将是之前update传递的内容和doFinal传递的内容的和。
//      byte[] result = cipher.doFinal(content.getBytes());
        String base64Result = Base64.getEncoder().encodeToString(result);//对加密后的字节数组进行Base64编码
        System.out.println("Result: " + base64Result);
        return base64Result;
    }
    /**
     * 解密测试
     */
    public static String getDecrpyt( String content) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        SecretKey secretKey = SecrityTool.geneKey();
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] encodedBytes = Base64.getDecoder().decode(content.getBytes());
        byte[] result = cipher.doFinal(encodedBytes);//对加密后的字节数组进行解密
        String ret=new String(result);
        System.out.println("Result: " + ret);
        return ret;
    }
}
